/*
 * CommunicationAdpt.h
 *
 */

#ifndef COMMUNICATIONADPT_H_
#define COMMUNICATIONADPT_H_

#include "MiddlewareCommon.h"
#include "../IPC/Semaphore.h"
#include "../IPC/MessageQueue.h"

namespace middleware {

class CommunicationAdpt {
public:
	typedef enum{RESERVAR=0,FIN_RESERVA,INSERTAR,RETIRAR}AdptRequestType;
	typedef enum{RESPUESTA_RESERVA=0,FIN_RESPUESTA_RESERVA,NO_HAY_ESPACIO}AdptReplyStatus;

	typedef enum{ADPT_HOST=0,VENDEDOR,ROBOT_16,UNDEFINED_TYPE}AdptCommunicationType;

	//For data alignment purposes (32/64 bit compatibility)
	#pragma pack(push, 1)
	struct AdptRequestStruct
	{
		AdptRequestType requestType;
		ProductoCantidad productosCantidades;
		int cantidadMinima;
		OrdenCompraHeader ordenCompra;
		Producto producto;
	};

	struct AdptReplyVendedorStruct
	{
		AdptReplyStatus status;
		ProductoCantidad productosCantidades;
	};
	struct AdptReplyRobot16Struct
	{
		Producto producto;
	};
	#pragma pack(pop)

public:
	CommunicationAdpt(std::string hostName);
	virtual ~CommunicationAdpt();

	bool reservarProductos(OrdenCompraHeader ordenCompra,
							  const ProductoCantidadList &productos,
							  ProductoCantidadList& productosReservados,
							  ProductoCantidadMap& cantidadesMinimas);

	void getExclusividad();


	void getAdptRequest(AdptRequestType &requestType,
						  ProductoCantidad &productos,
						  OrdenCompraHeader &ordenCompra,
						  Producto &producto,
						  int &cantMinima);

	void responderVendedor(AdptReplyStatus replyType,
							  int VendedorId,
							  ProductoCantidad prodCantidad = ProductoCantidad());

	void insertarProducto(Producto &producto);


	void retirarProducto(TipoProducto tipoProducto,
						   OrdenCompraHeader &ordenCompra,
						   Producto &producto);

	void entregarProducto(Producto &producto);

	static void launchForVendedor(std::string hostName, int vendedorId);

	static void create(AdptCommunicationType type,std::string hostName);
	static void destroy(AdptCommunicationType type,std::string hostName);

private:
	ipc::MessageQueue<AdptRequestStruct> m_RequestQueue;
	ipc::MessageQueue<AdptReplyVendedorStruct> m_VendedorReplyQueue;
	ipc::MessageQueue<AdptReplyRobot16Struct> m_Robot16ReplyQueue;
	
	int m_mTypeReq;
	int m_mTypeMutexReq;
	int	m_mtypeRobot16Req;

	static const std::string MUTEX_PATH;
	static const char MUTEX_KEY = 'd';
	static const Uid UIDRequest, UIDVendedorReply, UIDRobot16Reply;
};

} /* namespace middleware */
#endif /* COMMUNICATIONADPT_H_ */
